package middleware

import (
	"5title_gin/pkg/utils/http"
	"github.com/gin-gonic/gin"
	"sync"
	"time"
)

// LimitMiddleware 是限流中间件的封装，供 Gin 使用
func LimitMiddleware(limit int) gin.HandlerFunc {
	return NewLimiter(limit, 1*time.Second).Middleware
}

// Limiter 限流器结构体
type Limiter struct {
	limit      int                // 限制的请求数量
	duration   time.Duration      // 时间窗口
	timestamps map[string][]int64 // 存储 IP 请求时间戳
	mu         sync.Mutex         // 互斥锁，保证并发安全
}

// NewLimiter 创建新的限流器
func NewLimiter(limit int, duration time.Duration) *Limiter {
	return &Limiter{
		limit:      limit,
		duration:   duration,
		timestamps: make(map[string][]int64),
	}
}

// Middleware 是 Gin 限流中间件
func (l *Limiter) Middleware(c *gin.Context) {
	ip := c.ClientIP() // 获取客户端 IP
	now := time.Now().Unix()

	l.mu.Lock()         // 加锁，保证并发安全
	defer l.mu.Unlock() // 退出时解锁

	// 初始化该 IP 的请求记录
	if _, ok := l.timestamps[ip]; !ok {
		l.timestamps[ip] = []int64{}
	}

	// 过滤掉超出时间窗口的请求记录
	validTimestamps := []int64{}
	for _, ts := range l.timestamps[ip] {
		if ts >= now-int64(l.duration.Seconds()) {
			validTimestamps = append(validTimestamps, ts)
		}
	}
	l.timestamps[ip] = validTimestamps

	// 检查请求数量是否超限
	if len(l.timestamps[ip]) >= l.limit {
		http.FailWithMsg("请求太频繁，请稍后再试", c)
		c.Abort()
		return
	}

	// 记录当前请求时间戳
	l.timestamps[ip] = append(l.timestamps[ip], now)

	// 继续处理请求
	c.Next()
}
